//
//  BlueCommonData.m
//  WealthGoods
//
//  Created by yisheng chen on 2023/11/27.
//

#import "BlueCommonData.h"

@implementation BlueCommonData

#pragma mark 1.1 APP端发起更新
+ (NSData *)createFirmwareUpdatePacketWithFileSize:(NSUInteger)fileSize {
    NSMutableData *packet = [NSMutableData data];
    
    // 添加帧头
    const uint8_t frameHeader[] = {0x5A, 0xA5};
    [packet appendBytes:frameHeader length:sizeof(frameHeader)];
    
    // 添加指令
    const uint8_t command = 0x01;
    [packet appendBytes:&command length:1];
    
    // 文件大小转换为4字节，并添加
    uint8_t fileSizeBytes[4];
    fileSizeBytes[0] = (uint8_t)((fileSize >> 24) & 0xFF);
    fileSizeBytes[1] = (uint8_t)((fileSize >> 16) & 0xFF);
    fileSizeBytes[2] = (uint8_t)((fileSize >> 8) & 0xFF);
    fileSizeBytes[3] = (uint8_t)(fileSize & 0xFF);
    [packet appendBytes:fileSizeBytes length:sizeof(fileSizeBytes)];
    
    // 计算校验码
    uint8_t checksum = [self calculateChecksum:packet];
    [packet appendBytes:&checksum length:1];
    
    return packet;
}
#pragma mark 1.2 APP回复数据指令
+ (void)sendDataPacket:(NSData *)fileData andLocation:(NSInteger)location andBlock:(BlueDataBlock)block{

    NSUInteger length = [fileData length];
    NSUInteger offset = location;
    
    if(length > offset){
        NSUInteger chunkSize = MIN(length - offset, 384);
        NSData *chunk = [fileData subdataWithRange:NSMakeRange(offset, chunkSize)];
        NSData *packet = [self buildPacketWithData:chunk];
        block(packet);
    }
}

+ (NSData *)buildPacketWithData:(NSData *)data {
    NSMutableData *packet = [NSMutableData data];
    // 帧头
    [packet appendBytes:"\x5A\xA5" length:2];
    // 指令
    [packet appendBytes:"\x02" length:1];
    // 文件地址（示例地址，需要根据实际情况调整） 暂时写死
    [packet appendBytes:"\x00\x00\x00\x00" length:4];
    // 数据长度   暂时写死
    //UInt16 dataLength = CFSwapInt16HostToBig((UInt16)[data length]);
    [packet appendBytes:"\x00" length:1];
    //需要写一段判断【bety7 1个字节有效数字不足则为0x00或0xff】  暂时写死
    // 数据
    [packet appendData:data];
    // 校验码
    Byte sum = [self calculateChecksum:packet];
    [packet appendBytes:&sum length:1];
    
    return packet;
}
+ (void)sendPacket:(NSData *)packet {
    // 在这里实现发送数据包的逻辑，例如通过蓝牙或其他方式
    NSLog(@"Sending packet: %@", packet);
}
#pragma mark 1.3 设备的响应更新及请求文件数据0x03
+ (NSData *)buildPacketWithCommand:(Byte)command
                       fileAddress:(uint32_t)fileAddress
                       dataLength:(Byte)dataLength
                             data:(NSData *)data {
    NSMutableData *packet = [NSMutableData data];
    
    // 添加帧头
    [packet appendBytes:"\x5A\xA5" length:2];
    
    // 添加指令
    [packet appendBytes:&command length:1];
    
    // 添加文件地址
    uint32_t bigEndianAddress = CFSwapInt32HostToBig(fileAddress);
    [packet appendBytes:&bigEndianAddress length:4];
    
    // 添加数据长度
    [packet appendBytes:&dataLength length:1];
    
    // 添加数据
    [packet appendData:data];
    
    // 如果数据长度不是0xFF，则需要填充数据
    if (dataLength != 0xFF) {
        Byte padding[1] = {0xFF}; // 填充字节为0xFF
        [packet appendBytes:padding length:1];
    }
    
    // 计算校验码并添加
    Byte checksum = [self calculateChecksum:packet];
    [packet appendBytes:&checksum length:1];
    
    return packet;
}

+ (void)sendControlPacketWithFileAddress:(uint32_t)fileAddress dataLength:(Byte)dataLength andBlock:(BlueDataBlock)block{
    // 这里仅为示例，您需要根据实际的数据来设置
    NSData *controlData = nil; // 控制数据，需要根据您的需要来设定
    
    NSData *packet = [self buildPacketWithCommand:0x03
                                      fileAddress:fileAddress
                                      dataLength:dataLength
                                            data:controlData];
//    [self sendPacket:packet];
    block(packet);
}
#pragma mark 2.1 发起校验
+ (NSData *)buildCommandPacketWithVersion:(uint16_t)version {
    NSMutableData *packet = [NSMutableData data];
    
    // Frame header
    [packet appendBytes:"\x5A\xA5" length:2];
    
    // Command byte
    Byte command = 0x05;
    [packet appendBytes:&command length:1];
    
    // Version information
    uint16_t bigEndianVersion = CFSwapInt16HostToBig(version);
    [packet appendBytes:&bigEndianVersion length:2];
    
    // Checksum (simply add all previous bytes, then take complement + 1)
    Byte checksum = [self calculateChecksum:packet];
    [packet appendBytes:&checksum length:1];
    
    return packet;
}
#pragma mark 2.2 回应校验
+ (NSData *)buildResponsePacket{
    NSMutableData *packet = [NSMutableData data];
    
    // 添加帧头
    [packet appendBytes:"\x5A\xA5" length:2];
    
    // 添加指令字节
    Byte command = 0x05;
    [packet appendBytes:&command length:1];
    
    // 添加固定的响应数据
    uint16_t fixedResponse = 0xABAB;
    [packet appendBytes:&fixedResponse length:2];
    
    // 计算并添加校验和
    Byte checksum = [self calculateChecksum:packet];
    [packet appendBytes:&checksum length:1];
    
    return packet;
}
#pragma mark 3.3 获取版本号
+ (NSData *)buildCommandPacketWithVersionNum {
    NSMutableData *packet = [NSMutableData data];
    
    // 添加帧头
    const uint8_t frameHeader[] = {0x5A, 0xA5};
    [packet appendBytes:"\x5A\xA5" length:2];
    
    // 添加指令
    const uint32_t command = 0x08;
    [packet appendBytes:&command length:1];
    
    // 计算校验码
    uint8_t checksum = [self calculateChecksum:packet];
    [packet appendBytes:&checksum length:1];
    Byte *valueByte = (Byte *)[packet bytes];
    for(NSInteger i = 0;i < packet.length;i++){
        NSLog(@"%d",valueByte[i]);
    }
    NSLog(@"%@",packet);
    return packet;
}
#pragma mark 累加和取反加1
+ (uint8_t)calculateChecksum:(NSData *)data {
    const uint8_t *bytes = data.bytes;
    uint8_t sum = 0;
    for (NSUInteger i = 0; i < data.length; i++) {
        sum += bytes[i];
    }
    return ~sum + 1; // 累加和取反加1
}


@end
